import { requireToken } from "@/state/token";
import { mockEnabled, mockUrl } from "./mock";

function getBaseUrl() {
  const defaultPath = `${location.protocol}//${location.hostname}:8000`;

  if (import.meta.env.DEV && mockEnabled.value) {
    const overwritePath = mockUrl.value;
    if (overwritePath != null) {
      return overwritePath;
    }
  }

  return defaultPath;
}

async function request(path, method = "GET", body = null, sendToken = false) {
  try {
    const baseurl = getBaseUrl();
    const param = {
      method,
      headers: new Map()
    };

    if (body !== undefined && body !== null) {
      if (typeof body == "object") {
        param.body = JSON.stringify(body);
        param.headers.set("Content-Type", "application/json");
      } else if (typeof body == "string") {
        param.body = body;
      } else {
        throw Error("Unknown body: ${body}");
      }
    }

    if (sendToken) {
      const token = requireToken();
      param.headers.set("Authorization", `Bearer ${token}`);
    }

    const response = await fetch(`${baseurl}${path}`, param);
    if (!response.ok) {
      const text = await response.text();
      let message = null;
      try {
        const data = JSON.parse(text);
        if (data.message != null) {
          message = data.message;
        }
      } catch (_) {
        message = text;
      }
      if (message != null) {
        throw message;
      } else {
        throw `Status ${response.status} ${response.statusText}: ${text}`;
      }
    }

    if (response.status == 204) {
      return null;
    } else {
      return await response.json();
    }
  } catch (ex) {
    if (ex instanceof TypeError) {
      throw "网络错误";
    } else {
      throw ex;
    }
  }
}

export { request };
